home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 March / PCWorld_2001-03_cd.bin / Software / TemaCD / classbuild / ClassBuilder 2.2 PR405 Setup.exe / {app} / Include / CB_Multi.h < prev    next >
C/C++ Source or Header  |  2000-04-06  |  26KB  |  794 lines

  1. #ifndef CB_MULTI_H
  2. #define CB_MULTI_H
  3.  
  4. #include <assert.h>
  5.  
  6. #include "CB_IteratorMulti.h"
  7.  
  8. // defines for include files
  9. #define RELATION_TEMPLATE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  10. public:\
  11.     ClassTo* _first##NameTo;\
  12.     ClassTo* _last##NameTo;\
  13.     int _count##NameTo;\
  14. \
  15. public:\
  16.     void Add##NameTo##First(ClassTo* item)\
  17.     {\
  18.         METHOD_MULTI_ADDFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  19.     }\
  20.     void Add##NameTo##Last(ClassTo* item)\
  21.     {\
  22.         METHOD_MULTI_ADDLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  23.     }\
  24.     void Add##NameTo##After(ClassTo* item, ClassTo* pos)\
  25.     {\
  26.         METHOD_MULTI_ADDAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  27.     }\
  28.     void Add##NameTo##Before(ClassTo* item, ClassTo* pos)\
  29.     {\
  30.         METHOD_MULTI_ADDBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  31.     }\
  32.     void Remove##NameTo(ClassTo* item)\
  33.     {\
  34.         METHOD_MULTI_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  35.     }\
  36.     void Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  37.     {\
  38.         METHOD_MULTI_REPLACE(ClassFrom, NameFrom, ClassTo, NameTo) \
  39.     }\
  40.     void DeleteAll##NameTo()\
  41.     {\
  42.         METHOD_MULTI_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  43.     }\
  44.     ClassTo* GetFirst##NameTo() const\
  45.     {\
  46.         METHOD_MULTI_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  47.     }\
  48.     ClassTo* GetLast##NameTo() const\
  49.     {\
  50.         METHOD_MULTI_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  51.     }\
  52.     ClassTo* GetNext##NameTo(ClassTo* pos) const\
  53.     {\
  54.         METHOD_MULTI_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  55.     }\
  56.     ClassTo* GetPrev##NameTo(ClassTo* pos) const\
  57.     {\
  58.         METHOD_MULTI_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  59.     }\
  60.     int Get##NameTo##Count() const\
  61.     {\
  62.         METHOD_MULTI_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  63.     }\
  64.     void Move##NameTo##First(ClassTo* item)\
  65.     {\
  66.         METHOD_MULTI_MOVEFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  67.     }\
  68.     void Move##NameTo##Last(ClassTo* item)\
  69.     {\
  70.         METHOD_MULTI_MOVELAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  71.     }\
  72.     void Move##NameTo##After(ClassTo* item, ClassTo* pos)\
  73.     {\
  74.         METHOD_MULTI_MOVEAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  75.     }\
  76.     void Move##NameTo##Before(ClassTo* item, ClassTo* pos)\
  77.     {\
  78.         METHOD_MULTI_MOVEBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  79.     }\
  80.     void Sort##NameTo(int (*comp)(ClassTo*, ClassTo*))\
  81.     {\
  82.         METHOD_MULTI_SORT(ClassFrom, NameFrom, ClassTo, NameTo) \
  83.     }\
  84.     ITERATOR_TEMPLATE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  85.  
  86. #define RELATION_TEMPLATE_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  87. public:\
  88.     ClassTo* _first##NameTo;\
  89.     ClassTo* _last##NameTo;\
  90.     int _count##NameTo;\
  91. \
  92. public:\
  93.     void Add##NameTo##First(ClassTo* item)\
  94.     {\
  95.         METHOD_MULTI_ADDFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  96.     }\
  97.     void Add##NameTo##Last(ClassTo* item)\
  98.     {\
  99.         METHOD_MULTI_ADDLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  100.     }\
  101.     void Add##NameTo##After(ClassTo* item, ClassTo* pos)\
  102.     {\
  103.         METHOD_MULTI_ADDAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  104.     }\
  105.     void Add##NameTo##Before(ClassTo* item, ClassTo* pos)\
  106.     {\
  107.         METHOD_MULTI_ADDBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  108.     }\
  109.     void Remove##NameTo(ClassTo* item)\
  110.     {\
  111.         METHOD_MULTI_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  112.     }\
  113.     void Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  114.     {\
  115.         METHOD_MULTI_REPLACE(ClassFrom, NameFrom, ClassTo, NameTo) \
  116.     }\
  117.     void DeleteAll##NameTo()\
  118.     {\
  119.         METHOD_MULTI_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  120.     }\
  121.     ClassTo* GetFirst##NameTo() const\
  122.     {\
  123.         METHOD_MULTI_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  124.     }\
  125.     ClassTo* GetLast##NameTo() const\
  126.     {\
  127.         METHOD_MULTI_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  128.     }\
  129.     ClassTo* GetNext##NameTo(ClassTo* pos) const\
  130.     {\
  131.         METHOD_MULTI_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  132.     }\
  133.     ClassTo* GetPrev##NameTo(ClassTo* pos) const\
  134.     {\
  135.         METHOD_MULTI_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  136.     }\
  137.     int Get##NameTo##Count() const\
  138.     {\
  139.         METHOD_MULTI_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  140.     }\
  141.     void Move##NameTo##First(ClassTo* item)\
  142.     {\
  143.         METHOD_MULTI_MOVEFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  144.     }\
  145.     void Move##NameTo##Last(ClassTo* item)\
  146.     {\
  147.         METHOD_MULTI_MOVELAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  148.     }\
  149.     void Move##NameTo##After(ClassTo* item, ClassTo* pos)\
  150.     {\
  151.         METHOD_MULTI_MOVEAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  152.     }\
  153.     void Move##NameTo##Before(ClassTo* item, ClassTo* pos)\
  154.     {\
  155.         METHOD_MULTI_MOVEBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  156.     }\
  157.     void Sort##NameTo(int (*comp)(ClassTo*, ClassTo*))\
  158.     {\
  159.         METHOD_MULTI_SORT(ClassFrom, NameFrom, ClassTo, NameTo) \
  160.     }\
  161.     ITERATOR_TEMPLATE_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  162.  
  163. #define RELATION_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  164. public:\
  165.     ClassTo* _first##NameTo;\
  166.     ClassTo* _last##NameTo;\
  167.     int _count##NameTo;\
  168. \
  169. public:\
  170.     void Add##NameTo##First(ClassTo* item);\
  171.     void Add##NameTo##Last(ClassTo* item);\
  172.     void Add##NameTo##After(ClassTo* item, ClassTo* pos);\
  173.     void Add##NameTo##Before(ClassTo* item, ClassTo* pos);\
  174.     void Remove##NameTo(ClassTo* item);\
  175.     void RemoveAll##NameTo();\
  176.     void DeleteAll##NameTo();\
  177.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  178.     ClassTo* GetFirst##NameTo() const;\
  179.     ClassTo* GetLast##NameTo() const;\
  180.     ClassTo* GetNext##NameTo(ClassTo* pos) const;\
  181.     ClassTo* GetPrev##NameTo(ClassTo* pos) const;\
  182.     int Get##NameTo##Count() const;\
  183.     void Move##NameTo##First(ClassTo* item);\
  184.     void Move##NameTo##Last(ClassTo* item);\
  185.     void Move##NameTo##After(ClassTo* item, ClassTo* pos);\
  186.     void Move##NameTo##Before(ClassTo* item, ClassTo* pos);\
  187.     void Sort##NameTo(int (*comp)(ClassTo*, ClassTo*));\
  188.     ITERATOR_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  189.  
  190. #define RELATION_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  191. public:\
  192.     ClassTo* _first##NameTo;\
  193.     ClassTo* _last##NameTo;\
  194.     int _count##NameTo;\
  195. \
  196. public:\
  197.     void Add##NameTo##First(ClassTo* item);\
  198.     void Add##NameTo##Last(ClassTo* item);\
  199.     void Add##NameTo##After(ClassTo* item, ClassTo* pos);\
  200.     void Add##NameTo##Before(ClassTo* item, ClassTo* pos);\
  201.     void Remove##NameTo(ClassTo* item);\
  202.     void RemoveAll##NameTo();\
  203.     void DeleteAll##NameTo();\
  204.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  205.     ClassTo* GetFirst##NameTo() const;\
  206.     ClassTo* GetLast##NameTo() const;\
  207.     ClassTo* GetNext##NameTo(ClassTo* pos) const;\
  208.     ClassTo* GetPrev##NameTo(ClassTo* pos) const;\
  209.     int Get##NameTo##Count() const;\
  210.     void Move##NameTo##First(ClassTo* item);\
  211.     void Move##NameTo##Last(ClassTo* item);\
  212.     void Move##NameTo##After(ClassTo* item, ClassTo* pos);\
  213.     void Move##NameTo##Before(ClassTo* item, ClassTo* pos);\
  214.     void Sort##NameTo(int (*comp)(ClassTo*, ClassTo*));\
  215.     ITERATOR_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  216.  
  217. #define RELATION_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  218. public:\
  219.     ClassFrom* _ref##NameFrom;\
  220.     ClassTo* _prev##NameFrom;\
  221.     ClassTo* _next##NameFrom;\
  222. \
  223. public:\
  224.     ClassFrom* Get##NameFrom() const { return _ref##NameFrom; };
  225.  
  226. // defines implementation
  227. #define INIT_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  228.     _first##NameTo = (ClassTo*)0;\
  229.     _last##NameTo = (ClassTo*)0;\
  230.     _count##NameTo = 0;
  231.  
  232. #define EXIT_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  233.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  234.           Remove##NameTo(item);\
  235.     }
  236.  
  237. #define REPLACE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  238.     _first##NameTo = pOld->_first##NameTo;\
  239.     _last##NameTo = pOld->_last##NameTo;\
  240.     _count##NameTo = pOld->_count##NameTo;\
  241.     pOld->_first##NameTo = (ClassTo*)0;\
  242.     pOld->_last##NameTo = (ClassTo*)0;\
  243.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  244.           item->_ref##NameFrom = this; }
  245.  
  246. #define INIT_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  247.     _ref##NameFrom = (ClassFrom*)0;\
  248.     _prev##NameFrom = (ClassTo*)0;\
  249.     _next##NameFrom = (ClassTo*)0;
  250.  
  251. #define EXIT_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  252.     assert(this);\
  253.     if (_ref##NameFrom)\
  254.     {\
  255.         ClassFrom##::##NameTo##Iterator::Check(this);\
  256. \
  257.         _ref##NameFrom->_count##NameTo--;\
  258. \
  259.         if (_next##NameFrom)\
  260.             _next##NameFrom->_prev##NameFrom = _prev##NameFrom;\
  261.         else\
  262.             _ref##NameFrom->_last##NameTo = _prev##NameFrom;\
  263. \
  264.         if (_prev##NameFrom)\
  265.             _prev##NameFrom->_next##NameFrom = _next##NameFrom;\
  266.         else\
  267.             _ref##NameFrom->_first##NameTo = _next##NameFrom;\
  268. \
  269.         _prev##NameFrom = (ClassTo*)0;\
  270.         _next##NameFrom = (ClassTo*)0;\
  271.         _ref##NameFrom = (ClassFrom*)0;\
  272.     }
  273.  
  274. #define REPLACE_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  275.     assert(this);\
  276.     assert(pOld);\
  277.     if (pOld->_ref##NameFrom)\
  278.     {\
  279.         ClassFrom##::##NameTo##Iterator::Check(pOld, this);\
  280. \
  281.         _ref##NameFrom = pOld->_ref##NameFrom;\
  282. \
  283.         if (pOld->_next##NameFrom)\
  284.             pOld->_next##NameFrom->_prev##NameFrom = this;\
  285.         else\
  286.             _ref##NameFrom->_last##NameTo = this;\
  287. \
  288.         if (pOld->_prev##NameFrom)\
  289.             pOld->_prev##NameFrom->_next##NameFrom = this;\
  290.         else\
  291.             _ref##NameFrom->_first##NameTo = this;\
  292. \
  293.         _next##NameFrom = pOld->_next##NameFrom;\
  294.         _prev##NameFrom = pOld->_prev##NameFrom;\
  295. \
  296.         pOld->_ref##NameFrom = (ClassFrom*)0;\
  297.         pOld->_next##NameFrom = (ClassTo*)0;\
  298.         pOld->_prev##NameFrom = (ClassTo*)0;\
  299.     }\
  300.     else\
  301.     {\
  302.         _ref##NameFrom = (ClassFrom*)0;\
  303.         _prev##NameFrom = (ClassTo*)0;\
  304.         _next##NameFrom = (ClassTo*)0;\
  305.     }
  306.  
  307. #define REMOVE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  308.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  309.       {\
  310.           (void)new UndoSubChange(item);\
  311.           Remove##NameTo(item);\
  312.       } }
  313.  
  314. #define SAVE_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  315.     p##ClassTo->_ref##NameFrom = _ref##NameFrom;\
  316.     p##ClassTo->_prev##NameFrom = _prev##NameFrom;\
  317.     p##ClassTo->_next##NameFrom = _next##NameFrom;
  318.  
  319. #define RESTORE_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  320.     if (p##ClassTo == this)\
  321.     {\
  322.         if (_ref##NameFrom)\
  323.         {\
  324.             _ref##NameFrom->_count##NameTo++;\
  325. \
  326.             assert(!_prev##NameFrom || !_next##NameFrom || \
  327.             (_prev##NameFrom->_next##NameFrom == _next##NameFrom && \
  328.             _next##NameFrom->_prev##NameFrom == _prev##NameFrom));\
  329.             if (_prev##NameFrom)\
  330.                 _prev##NameFrom->_next##NameFrom = this;\
  331.             else\
  332.                 _ref##NameFrom->_first##NameTo = this;\
  333. \
  334.             if (_next##NameFrom)\
  335.                 _next##NameFrom->_prev##NameFrom = this;\
  336.             else\
  337.                 _ref##NameFrom->_last##NameTo = this;\
  338.         }\
  339.     }\
  340.     else if (_ref##NameFrom != p##ClassTo->_ref##NameFrom || \
  341.              _prev##NameFrom != p##ClassTo->_prev##NameFrom || \
  342.              _next##NameFrom != p##ClassTo->_next##NameFrom )\
  343.     {\
  344.         if (_ref##NameFrom)\
  345.         {\
  346.             ClassFrom##::##NameTo##Iterator::Check(this);\
  347. \
  348.             _ref##NameFrom->_count##NameTo--;\
  349. \
  350.             if (_next##NameFrom)\
  351.                 _next##NameFrom->_prev##NameFrom = _prev##NameFrom;\
  352.             else\
  353.                 _ref##NameFrom->_last##NameTo = _prev##NameFrom;\
  354. \
  355.             if (_prev##NameFrom)\
  356.                 _prev##NameFrom->_next##NameFrom = _next##NameFrom;\
  357.             else\
  358.                 _ref##NameFrom->_first##NameTo = _next##NameFrom;\
  359.         }\
  360.         _ref##NameFrom = p##ClassTo->_ref##NameFrom;\
  361.         _prev##NameFrom = p##ClassTo->_prev##NameFrom;\
  362.         _next##NameFrom = p##ClassTo->_next##NameFrom;\
  363.         if (_ref##NameFrom)\
  364.         {\
  365.             _ref##NameFrom->_count##NameTo++;\
  366. \
  367.             assert(!_prev##NameFrom || !_next##NameFrom || \
  368.             (_prev##NameFrom->_next##NameFrom == _next##NameFrom && \
  369.             _next##NameFrom->_prev##NameFrom == _prev##NameFrom));\
  370.             if (_prev##NameFrom)\
  371.                 _prev##NameFrom->_next##NameFrom = this;\
  372.             else\
  373.                 _ref##NameFrom->_first##NameTo = this;\
  374.         \
  375.             if (_next##NameFrom)\
  376.                 _next##NameFrom->_prev##NameFrom = this;\
  377.             else\
  378.                 _ref##NameFrom->_last##NameTo = this;\
  379.         }\
  380.     }
  381.  
  382. #define REMOVE_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  383.     if (_ref##NameFrom)\
  384.     {\
  385.         ClassFrom##::##NameTo##Iterator::Check(this);\
  386. \
  387.         _ref##NameFrom->_count##NameTo--;\
  388. \
  389.         if (_next##NameFrom)\
  390.             _next##NameFrom->_prev##NameFrom = _prev##NameFrom;\
  391.         else\
  392.             _ref##NameFrom->_last##NameTo = _prev##NameFrom;\
  393. \
  394.         if (_prev##NameFrom)\
  395.             _prev##NameFrom->_next##NameFrom = _next##NameFrom;\
  396.         else\
  397.             _ref##NameFrom->_first##NameTo = _next##NameFrom;\
  398.     }
  399.  
  400. #define CLEANUP_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  401.     _ref##NameFrom = (ClassFrom*)0;\
  402.     _prev##NameFrom = (ClassTo*)0;\
  403.     _next##NameFrom = (ClassTo*)0;
  404.  
  405. #define METHODS_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  406. void ClassFrom##::Add##NameTo##First(ClassTo* item)\
  407. {\
  408.     METHOD_MULTI_ADDFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  409. }\
  410. \
  411. void ClassFrom##::Add##NameTo##Last(ClassTo* item)\
  412. {\
  413.     METHOD_MULTI_ADDLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  414. }\
  415. \
  416. void ClassFrom##::Add##NameTo##After(ClassTo* item, ClassTo* pos)\
  417. {\
  418.     METHOD_MULTI_ADDAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  419. }\
  420. \
  421. void ClassFrom##::Add##NameTo##Before(ClassTo* item, ClassTo* pos)\
  422. {\
  423.     METHOD_MULTI_ADDBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  424. }\
  425. \
  426. void ClassFrom##::Remove##NameTo(ClassTo* item)\
  427. {\
  428.     METHOD_MULTI_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  429. }\
  430. \
  431. void ClassFrom##::RemoveAll##NameTo()\
  432. {\
  433.     METHOD_MULTI_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  434. }\
  435. \
  436. void ClassFrom##::DeleteAll##NameTo()\
  437. {\
  438.     METHOD_MULTI_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  439. }\
  440. \
  441. void ClassFrom##::Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  442. {\
  443.     METHOD_MULTI_REPLACE(ClassFrom, NameFrom, ClassTo, NameTo) \
  444. }\
  445. \
  446. ClassTo* ClassFrom##::GetFirst##NameTo() const\
  447. {\
  448.     METHOD_MULTI_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  449. }\
  450. \
  451. ClassTo* ClassFrom##::GetLast##NameTo() const\
  452. {\
  453.     METHOD_MULTI_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  454. }\
  455. \
  456. ClassTo* ClassFrom##::GetNext##NameTo(ClassTo* pos) const\
  457. {\
  458.     METHOD_MULTI_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  459. }\
  460. \
  461. ClassTo* ClassFrom##::GetPrev##NameTo(ClassTo* pos) const\
  462. {\
  463.     METHOD_MULTI_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  464. }\
  465. \
  466. int ClassFrom##::Get##NameTo##Count() const\
  467. {\
  468.     METHOD_MULTI_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  469. }\
  470. \
  471. void ClassFrom##::Move##NameTo##First(ClassTo* item)\
  472. {\
  473.     METHOD_MULTI_MOVEFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  474. }\
  475. \
  476. void ClassFrom##::Move##NameTo##Last(ClassTo* item)\
  477. {\
  478.     METHOD_MULTI_MOVELAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  479. }\
  480. \
  481. void ClassFrom##::Move##NameTo##After(ClassTo* item, ClassTo* pos)\
  482. {\
  483.     METHOD_MULTI_MOVEAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  484. }\
  485. \
  486. void ClassFrom##::Move##NameTo##Before(ClassTo* item, ClassTo* pos)\
  487. {\
  488.     METHOD_MULTI_MOVEBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  489. }\
  490. \
  491. void ClassFrom##::Sort##NameTo##(int (*comp)(ClassTo*, ClassTo*))\
  492. {\
  493.     METHOD_MULTI_SORT(ClassFrom, NameFrom, ClassTo, NameTo) \
  494. }
  495.  
  496. #define METHOD_MULTI_ADDFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  497.     assert(this);\
  498. \
  499.     assert(item);\
  500.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  501. \
  502.     _count##NameTo++;\
  503. \
  504.     item->_ref##NameFrom = this;\
  505. \
  506.     if (_first##NameTo)\
  507.     {\
  508.         _first##NameTo->_prev##NameFrom = item;\
  509.         item->_next##NameFrom = _first##NameTo;\
  510.         _first##NameTo = item;\
  511.     }\
  512.     else\
  513.         _first##NameTo = _last##NameTo = item;
  514.  
  515. #define METHOD_MULTI_ADDLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  516.     assert(this);\
  517. \
  518.     assert(item);\
  519.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  520. \
  521.     _count##NameTo++;\
  522. \
  523.     item->_ref##NameFrom = this;\
  524. \
  525.     if (_last##NameTo)\
  526.     {\
  527.         _last##NameTo->_next##NameFrom = item;\
  528.         item->_prev##NameFrom = _last##NameTo;\
  529.         _last##NameTo = item;\
  530.     }\
  531.     else\
  532.         _first##NameTo = _last##NameTo = item;
  533.  
  534. #define METHOD_MULTI_ADDAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  535.     assert(this);\
  536. \
  537.     assert(item);\
  538.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  539. \
  540.     assert(pos);\
  541.     assert(pos->_ref##NameFrom == this);\
  542. \
  543.     _count##NameTo++;\
  544. \
  545.     item->_ref##NameFrom = this;\
  546.     item->_prev##NameFrom = pos;\
  547.     item->_next##NameFrom = pos->_next##NameFrom;\
  548.     pos->_next##NameFrom  = item;\
  549. \
  550.     if (item->_next##NameFrom)\
  551.         item->_next##NameFrom->_prev##NameFrom = item;\
  552.     else\
  553.         _last##NameTo = item;
  554.  
  555. #define METHOD_MULTI_ADDBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  556.     assert(this);\
  557. \
  558.     assert(item);\
  559.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  560. \
  561.     assert(pos);\
  562.     assert(pos->_ref##NameFrom == this);\
  563. \
  564.     _count##NameTo++;\
  565. \
  566.     item->_ref##NameFrom = this;\
  567.     item->_next##NameFrom = pos;\
  568.     item->_prev##NameFrom = pos->_prev##NameFrom;\
  569.     pos->_prev##NameFrom  = item;\
  570. \
  571.     if (item->_prev##NameFrom)\
  572.         item->_prev##NameFrom->_next##NameFrom = item;\
  573.     else\
  574.         _first##NameTo = item;
  575.  
  576. #define METHOD_MULTI_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  577.     assert(this);\
  578. \
  579.     assert(item);\
  580.     assert(item->_ref##NameFrom == this);\
  581. \
  582.     ClassFrom##::##NameTo##Iterator::Check(item);\
  583. \
  584.     _count##NameTo--;\
  585. \
  586.     if (item->_next##NameFrom)\
  587.         item->_next##NameFrom->_prev##NameFrom = item->_prev##NameFrom;\
  588.     else\
  589.         _last##NameTo = item->_prev##NameFrom;\
  590. \
  591.     if (item->_prev##NameFrom)\
  592.         item->_prev##NameFrom->_next##NameFrom = item->_next##NameFrom;\
  593.     else\
  594.         _first##NameTo = item->_next##NameFrom;\
  595. \
  596.     item->_prev##NameFrom = (ClassTo*)0;\
  597.     item->_next##NameFrom = (ClassTo*)0;\
  598.     item->_ref##NameFrom = (ClassFrom*)0;
  599.  
  600. #define METHOD_MULTI_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  601.     assert(this);\
  602. \
  603.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  604.           Remove##NameTo(item);
  605.  
  606. #define METHOD_MULTI_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  607.     assert(this);\
  608. \
  609.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  610.           delete item;
  611.  
  612. #define METHOD_MULTI_REPLACE(ClassFrom, NameFrom, ClassTo, NameTo) \
  613.     assert(this);\
  614. \
  615.     assert(item);\
  616.     assert(item->_ref##NameFrom == this);\
  617. \
  618.     assert(newItem);\
  619.     assert(newItem->_ref##NameFrom == (ClassFrom*)0);\
  620. \
  621.     ClassFrom##::##NameTo##Iterator::Check(item, newItem);\
  622. \
  623.     if (item->_next##NameFrom)\
  624.         item->_next##NameFrom->_prev##NameFrom = newItem;\
  625.     else\
  626.         _last##NameTo = newItem;\
  627. \
  628.     if (item->_prev##NameFrom)\
  629.         item->_prev##NameFrom->_next##NameFrom = newItem;\
  630.     else\
  631.         _first##NameTo = newItem;\
  632. \
  633.     newItem->_next##NameFrom = item->_next##NameFrom;\
  634.     newItem->_prev##NameFrom = item->_prev##NameFrom;\
  635.     item->_next##NameFrom = (ClassTo*)0;\
  636.     item->_prev##NameFrom = (ClassTo*)0;\
  637. \
  638.     item->_ref##NameFrom = (ClassFrom*)0;\
  639.     newItem->_ref##NameFrom = this;
  640.  
  641. #define METHOD_MULTI_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  642.     assert(this);\
  643.     return _first##NameTo;
  644.  
  645. #define METHOD_MULTI_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  646.     assert(this);\
  647.     return _last##NameTo;
  648.  
  649. #define METHOD_MULTI_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  650.     assert(this);\
  651. \
  652.     if (pos == (ClassTo*)0)\
  653.         return _first##NameTo;\
  654. \
  655.     assert(pos);\
  656.     assert(pos->_ref##NameFrom == this);\
  657. \
  658.     return pos->_next##NameFrom;
  659.  
  660. #define METHOD_MULTI_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  661.     assert(this);\
  662. \
  663.     if (pos == (ClassTo*)0)\
  664.         return _last##NameTo;\
  665. \
  666.     assert(pos);\
  667.     assert(pos->_ref##NameFrom == this);\
  668. \
  669.     return pos->_prev##NameFrom;
  670.  
  671. #define METHOD_MULTI_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  672.     assert(this);\
  673.     return _count##NameTo;
  674.  
  675. #define METHOD_MULTI_MOVEFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  676.     assert(item);\
  677.     assert(item->_ref##NameFrom);\
  678.     item->_ref##NameFrom->Remove##NameTo(item);\
  679.     Add##NameTo##First(item);
  680.  
  681. #define METHOD_MULTI_MOVELAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  682.     assert(item);\
  683.     assert(item->_ref##NameFrom);\
  684.     item->_ref##NameFrom->Remove##NameTo(item);\
  685.     Add##NameTo##Last(item);
  686.  
  687. #define METHOD_MULTI_MOVEAFTER(ClassFrom, NameFrom, ClassTo, NameTo) \
  688.     assert(item);\
  689.     assert(item->_ref##NameFrom);\
  690.     item->_ref##NameFrom->Remove##NameTo(item);\
  691.     Add##NameTo##After(item, pos);
  692.  
  693. #define METHOD_MULTI_MOVEBEFORE(ClassFrom, NameFrom, ClassTo, NameTo) \
  694.     assert(item);\
  695.     assert(item->_ref##NameFrom);\
  696.     item->_ref##NameFrom->Remove##NameTo(item);\
  697.     Add##NameTo##Before(item, pos);
  698.  
  699. #define METHOD_MULTI_SORT(ClassFrom, NameFrom, ClassTo, NameTo) \
  700.     for (ClassTo* a = GetFirst##NameTo(); a; a = GetNext##NameTo(a))\
  701.     {\
  702.         ClassTo* b = GetNext##NameTo(a);\
  703. \
  704.         while (b && (comp(a, b) > 0))\
  705.         {\
  706.             ClassTo* c = GetPrev##NameTo(a);\
  707.             while (c && (comp(c, b) > 0))\
  708.                 c = GetPrev##NameTo(c);\
  709. \
  710.             if (c)\
  711.                 Move##NameTo##After(b, c);\
  712.             else\
  713.                 Move##NameTo##First(b);\
  714. \
  715.             b = GetNext##NameTo(a);\
  716.         }\
  717.     }
  718.  
  719. #define METHODS_MULTI_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  720.  
  721. #define SERIALIZE_ALL_OBJECTS(Document, DocumentName, DocumentBase, DocumentBaseName) \
  722.     if (rCArchive.IsStoring())\
  723.     {\
  724.         /* Write the number of objects to store.*/\
  725.         rCArchive << Get##DocumentBaseName##Count();\
  726. \
  727.         /* Reserve index = 0; for the NULL pointer*/\
  728.         int index = 1;\
  729. \
  730.         /* Write the data of the objects*/\
  731.         DocumentBase* object;\
  732.         for (object = GetFirst##DocumentBaseName(); object; object = GetNext##DocumentBaseName(object))\
  733.         {\
  734.             object->_index = index++;\
  735.             rCArchive << object;\
  736.         }\
  737. \
  738.         /* Write relations of Document*/\
  739.         SerializeRelations(rCArchive, NULL);\
  740. \
  741.         /* Write all other objects relations*/\
  742.         for (object = GetFirst##DocumentBaseName(); object; object = GetNext##DocumentBaseName(object))\
  743.         {\
  744.             object->SerializeRelations(rCArchive, NULL);\
  745.         }\
  746.    }\
  747.    else\
  748.    {\
  749.         /* Read the number of objects stored*/\
  750.         int objectCount;\
  751.         rCArchive >> objectCount;\
  752. \
  753.         /* Make an array for the pointer mapping*/\
  754.         DocumentBase** pointerArray = new DocumentBase*[objectCount+1];\
  755.         pointerArray[0] = NULL;\
  756. \
  757.         /* Read the data of the objects*/\
  758.         for (int index = 1; index <= objectCount; index++)\
  759.         {\
  760.             CObject* pCObject;\
  761.             rCArchive >> pCObject;\
  762.             pointerArray[index] = (DocumentBase*)pCObject;\
  763.         }\
  764. \
  765.         /* Read relations of Document*/\
  766.         SerializeRelations(rCArchive, pointerArray);\
  767. \
  768.         /* Read all other objects relations*/\
  769.         for (index = 1; index <= objectCount; index++)\
  770.             pointerArray[index]->SerializeRelations(rCArchive, pointerArray);\
  771. \
  772.         delete pointerArray;\
  773.     }
  774.  
  775. #define WRITE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  776.         rCArchive << Get##NameTo##Count();\
  777.         { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  778.               rCArchive << item->_index; }
  779.  
  780. #define READ_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  781.             {\
  782.                 int count;\
  783.                 int index;\
  784.                 \
  785.                 rCArchive >> count;\
  786.                 for (int i = 0; i < count; i++)\
  787.                 {\
  788.                     rCArchive >> index;\
  789.                     Add##NameTo##Last((ClassTo*)(pointerArray[index]));\
  790.                 }\
  791.             }
  792.  
  793. #endif
  794.